home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
quartz
/
quartz10.lha
/
src
/
runtime
/
mcount.s
< prev
next >
Wrap
Text File
|
1990-05-08
|
4KB
|
199 lines
#include "asmdefs.h"
.file "mcount.s"
.data
.align 2
.text
.align 2
.globl mcountRet
.globl mcount
.globl _AtomicIncrPtr
.globl _AtomicDecrPtr
_AtomicIncrPtr:
movl 4(%esp) , %eax
lock incl (%eax)
ret
_AtomicDecrPtr:
movl 4(%esp) , %eax
lock decl (%eax)
ret
/* I have to bend over backwards to make this re-entrant (interrupts)
and to work with dbx
Initially, idPtr points to &idStack[0] with Start's ID.
*/
#define FetchEPtr(t,e) \
movl [_pP + pP_thread] , t ;\
movl Thread_id_top(t) , e
/* Register definitions */
#define calleeID %eax
#define callerID %ecx
#define calleeFP %edx
#define callerPC calleeFP
#define graph callerPC
#define me %ecx
#define ePtr %edx
#define tmpd ePtr
#define newFP %eax
#define newCalleeFP %eax
#define callerFP %ecx
#define size2 callerFP
#define size1 calleeFP
/* Some random rare conditions */
overflow:
pushl calleeID /* save for later */
pushl callerID
pushl graph /* args */
pushl callerID
pushl calleeID
call _ProfileMustAdd
addl $ 12 , %esp
popl callerID /* get these back */
popl calleeID
jmp idStack
outOfRoom:
call _OutOfRoom
jmp done
tooHigh:
call _TooHigh
jmp done
recursiveCall: /* clear the Overhead bit */
FetchEPtr(%edx,%edx)
movl callerID, IdEntry_id(%edx)
done:
leave
noProfile:
ret
/* Entry point for procedures: assumes address of calleeID is loaded */
mcount:
cmpl $ 0 , _profileOn
je noProfile
pushl %ebp
movl %esp , %ebp
FetchEPtr(%edx,%edx)
movl IdEntry_id(%edx) , callerID
testl $ OverheadState, callerID
jne done
orl $ OverheadState , callerID
movl callerID , IdEntry_id(%edx)
andl $ AllOffMask , callerID
/* movl (calleeID) , calleeID */
/* uses calleeID, callerID, calleeFP == callerPC = graph */
callCount:
movl (%ebp) , calleeFP
movl ReturnPC(calleeFP) , callerPC
cmpl _mEndOfText , callerPC
jge tooHigh
andl $OffPCTableBits , callerPC
addl _pcTable, callerPC /* is now: graph */
cmpl Graph_calleeID(graph) , calleeID
jne overflow
cmpl Graph_callerID(graph) , callerID
jne overflow
lock incl Graph_num(graph)
idStack:
cmpl callerID, calleeID
je recursiveCall /* ignore recursive calls */
/* uses calleeID, me, ePtr */
FetchEPtr(me,ePtr)
cmpl Thread_id_limit(me) , ePtr
jge outOfRoom /* check for overflow */
fillIdEntry:
andl $ OverheadOffMask, IdEntry_id(ePtr)
addl $ IdSize , ePtr
movl $ NoID , IdEntry_id(ePtr)
movl ePtr , Thread_id_top(me)
#ifdef PARANOID
orl $ OverheadState, calleeID
movl calleeID , IdEntry_id(ePtr)
/* Munge the stack so that we return to mcountRet */
/* Assumes nothing is saved from above */
mungeStack:
movl (%ebp), calleeFP
movl (calleeFP) , callerFP
subl calleeFP , callerFP /* now size2 */
subl size2 , %esp
movl %esp, newFP /* save top of stack */
pushl %esi
pushl %edi
subl %ebp , calleeFP /* now size1 */
addl size1 , size2 /* now size1 + size2 -- better be ecx */
shrl $2, size2 /* # of words to be moved */
movl newFP , %edi
movl %ebp, %esi
/* put us into a pseudo-stable intermediate state, before trashing old frame */
movl (%ebp), %ebp
rep smovl
addl size1,newFP /* now newCalleeFP = (oldCalleeFP + size2) */
movl %ebp, (newCalleeFP)
movl $ mcountRet, 4(newCalleeFP)
popl %edi
popl %esi
addl $4, %esp /* the fp that was saved on the stack is trash */
movl newCalleeFP,%ebp
/* Turn off overhead flag */
movl [_pP + pP_thread] , me
movl Thread_id_top(me) , ePtr
andl $ OverheadOffMask , IdEntry_id(ePtr)
ret
/* Dont use eax -- it has the return value */
mcountRet:
movl [_pP + pP_thread], me
addl $ - IdSize, Thread_id_top(me)
leave
ret
#else
movl calleeID , IdEntry_id(ePtr)
movl (%ebp) , %ecx
movl ReturnPC(%ecx) , %eax
movl %eax , IdEntry_pc(ePtr)
movl $ mcountRet , ReturnPC(%ecx)
leave
ret
/* don't use %eax */
mcountRet:
FetchEPtr(me,ePtr)
movl IdEntry_pc(ePtr),tmpd
addl $ - IdSize, Thread_id_top(me)
jmp *tmpd
#endif